INITSEG     equ 0x9000
SYSSEG      equ 0x1000
SETUPSEG    equ 0x9020

start:
    mov ax, INITSEG
    mov ds, ax
    mov ah, 0x03
    xor bh, bh
    int 0x10
    mov [0], dx         ; 光标位置

    mov ah, 0x88
    int 0x15
    mov [2], ax         ; 扩展内存数

    mov ah, 0x0f
    int 0x10
    mov [4], bx         ; 显示页面
    mov [6], ax         ; 显示模式、字符列数

    mov ah, 0x12
    mov bl, 0x10
    int 0x10
    mov [8], ax         ; ??
    mov [10], bx        ; 显示内存、显示状态
    mov [12], cx        ; 特性参数

    mov ax, 0x0000
    mov ds, ax
    lds si, [4 * 0x41]  ; 取中断向量0x41的值，即hd0参数表的地址->ds:si
    mov ax, INITSEG
    mov es, ax
    mov di, 0x0080      ; 传输的目的地址es:di(0x9000:0x0080)
    mov cx, 0x10        ; 共传输0x10字节
    rep
    movsb

    mov ax, 0x0000
    mov ds, ax
    lds si, [4 * 0x46]  ; 取中断向量0x46的值，即hd1参数表的地址->ds:si
    mov ax, INITSEG
    mov es, ax
    mov di, 0x0090      ; 传输的目的地址es:di(0x9000:0x0090)
    mov cx, 0x10
    rep
    movsb

; 检查是否有第二个硬盘，不存在就把第二个表清零
    mov ax, 0x1500
    mov dl, 0x81
    int 0x13
    jc  no_disk1
    cmp ah, 3
    je  is_disk1
no_disk1:
    mov ax, INITSEG
    mov es, ax
    mov di, 0x0090
    mov cx, 0x10
    mov ax, 0x00
    rep
    stosb
is_disk1:
    cli                 ; 保护模式下中断机制尚未建立，应禁止中断
    mov ax, 0x00
    cld
do_move:                ; 将内核从0x10000移动到0x00
    mov es, ax
    add ax, 0x1000
    cmp ax, 0x9000
    jz  end_move
    mov ds, ax
    sub di, di
    sub si, si
    mov cx, 0x8000
    rep
    movsw               ; 每次移动64KB数据
    jmp do_move

end_move:
    mov ax, SETUPSEG
    mov ds, ax
    lgdt    [gdt_48]    ; 加载gdtr

    mov al, 2
    out 0x92, al        ; 开A20

    mov ax, 0x0001
    lmsw    ax          ; 设置CR0的PE位
    jmp 8:0

gdt:
    dw  0, 0, 0, 0
    dw  0x07ff, 0x0000, 0x9a00, 0x00c0
    dw  0x07ff, 0x0000, 0x9200, 0x00c0

gdt_48:
    dw  0x800
    dw  512 + gdt, 0x9  ; 0x90200+gdt